import Flutter
import UIKit

public class SwiftAdSuyiFlutterSdkPlugin: NSObject, FlutterPlugin {
    
    static var channel: FlutterMethodChannel?
    
    static let instance = SwiftAdSuyiFlutterSdkPlugin() 
    
    public static func register(with registrar: FlutterPluginRegistrar) {
        channel = FlutterMethodChannel(name: "ad_suyi_sdk", binaryMessenger: registrar.messenger()) // 创建方法通道并设置名称
        registrar.addMethodCallDelegate(instance, channel: channel!) // 在FlutterPluginRegistrar上注册方法通道
        registrar.register(ADSuyiFlutterAdViewFactory(), withId: "ADSuyiAdView"); // 注册自定义广告视图
    }

    public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
        ADSuyiSDK.enablePersonalInformation = true; //开发者自行设置即可
        ADSuyiSDK.setLogLevel(.verbose) // 设置日志输出等级
        ADSuyiSDK.isFlutter = true // 设置该项目是flutter项目
        if(call.method == "initSdk") {
            let appId = call.arguments
            //初始化sdk
            ADSuyiSDK.initWithAppId(appId as! String) { (error) in
                print("\(String(describing: error))")
            }
            result(nil)
            return
        }
        
        guard let dic: Dictionary<String, Any> = call.arguments as? Dictionary<String, Any> else {
            result(nil)
            return;
        }
        guard let adId = dic["adId"] as? Int else {
            result(nil)
            return;
        }
        switch call.method {
        case "loadSplashAd": do { // 加载并展示开屏广告
            guard let posId = dic["posId"] as? String else {
                result(nil)
                return
            }
            let imgName = dic["imgName"] as? String
            let imgLogoName = dic["imgLogoName"] as? String
            ADSuyiFlutterSplashAd.shared.loadAndShow(posid: posId, adId: adId, imgName: imgName, imgLogoName: imgLogoName)
            result(nil)
        }
        case "loadOnlySplashAd": do { //加载开屏广告
            guard let posId = dic["posId"] as? String else {
                result(nil)
                return
            }
            let imgName = dic["imgName"] as? String
            let imgLogoName = dic["imgLogoName"] as? String
            ADSuyiFlutterSplashAd.shared.loadAd(posid: posId, adId: adId, imgName: imgName, imgLogoName: imgLogoName)
            result(nil)
        }
        case "showSplashAd": do { //展示开屏广告
            ADSuyiFlutterSplashAd.shared.showAd()
            result(nil)
        }
       
        case "loadRewardAd": do { // 加载激励视频广告
            guard let posId = dic["posId"] as? String else {
                result(nil)
                return
            }
            ADSuyiFlutterRewardAd.shared.load(posId: posId, adId: adId)
            result(nil)
        }
        case "showRewardAd": do { //展示激励视频广告
            ADSuyiFlutterRewardAd.shared.show(adId: adId)
            result(nil)
        }
        case "loadIntertitialAd": do { //加载插屏广告
            guard let posId = dic["posId"] as? String else {
                result(nil)
                return
            }
            ADSuyiFlutterIntertitialAd.shared.load(posId: posId, adId: adId)
            result(nil)
        }
        case "showIntertitialAd": do { //展示插屏广告
            ADSuyiFlutterIntertitialAd.shared.show(adId: adId)
            result(nil)
        }
        case "loadFullScreenVodAd": do { //加载全屏视频广告
            guard let posId = dic["posId"] as? String else {
                result(nil)
                return
            }
            ADSuyiFlutterFullScreenVodAd.shared.load(posId: posId, adId: adId)
            result(nil)
        }
        case "showFullScreenVodAd": do { // 展示全屏视频广告
            ADSuyiFlutterFullScreenVodAd.shared.show(adId: adId)
            result(nil)
        }
        case "loadBannerAd": do { // 加载横幅广告
            guard let posId = dic["posId"] as? String,
                  let adWidth = dic["adWidth"] as? Double,
                  let adHeight = dic["adHeight"] as? Double else {
                result(nil)
                return
            }
            ADSuyiFlutterBannerAd.shared.load(posId: posId, adId: adId, adWidth:adWidth, adHeight:adHeight)
            result(nil)
        }
        case "removeAd": do {
            ADSuyiFlutterAdMap.shared.deleteAd(adId: adId)
            result(nil)
        }
        case "loadNativeAd": do { // 加载信息流广告
            guard let posId = dic["posId"] as? String,
                  let adWidth = dic["adWidth"] as? Double else {
                result(nil)
                return
            }
            ADSuyiFlutterNativeAd.shared.loadNativeAd(posId, adId: adId, width: CGFloat(adWidth))
        }
        default: do {
            result(nil)
        }
        }
    }
}

func getEcpmPrecisionWithType(type:Int) -> String{
    switch type {
    case 1:
        return "精准"
    case 2:
        return "平台指定"
    case 3:
        return "估算"
    default:
        return "未返回"
    }
}

func getNewAdId() -> Int {
    struct Temp {
        static var adId = 0
    }
    Temp.adId -= 1;
    return Temp.adId;
}

class ADSuyiFlutterAdMap {
    static let shared = ADSuyiFlutterAdMap()
    
    var adMap = Dictionary<Int, NSObject>()
    var keyMap = Dictionary<NSObject, Int>()
    
    var nativeViewMap = Dictionary<Int,UIView>()
    var nativeViewKeyMap = Dictionary<UIView,Int>()
    // 存储广告对象
    func saveAd(ad: NSObject, adId: Int) {
        adMap[adId] = ad
        keyMap[ad] = adId
    }
    // 通过adId获取对应的广告对象
    func readAd(adId: Int) -> NSObject? {
        return adMap[adId]
    }
    // 通过广告对象获取对应的adId
    func readAdId(ad: NSObject) -> Int {
        return keyMap[ad] ?? -1
    }
    // 移除存储的广告对象和adId
    func deleteAd(adId: Int) {
        if let ad = readAd(adId: adId) {
            adMap.removeValue(forKey: adId)
            keyMap.removeValue(forKey: ad)
        }
    }
    // MARK:信息流方法 
    func saveNativeView(adView:UIView, adViewId:Int) {
        nativeViewMap[adViewId] = adView
        nativeViewKeyMap[adView] = adViewId;
    }
    
    func readNativeView(adViewId:Int) -> UIView? {
        return nativeViewMap[adViewId];
    }
    func readNativeViewId(adView:UIView) -> Int {
        return nativeViewKeyMap[adView] ?? -1
    }
    
    func deleteNativeAdView(adViewId:Int) {
        if let adView = readNativeView(adViewId: adViewId) {
            nativeViewMap.removeValue(forKey: adViewId)
            nativeViewKeyMap.removeValue(forKey: adView)
        }
    }
    
    
}

public class ADSuyiFlutterAdView : UIView, FlutterPlatformView {
    
    var adView : UIView?
    
    public func view() -> UIView {
        return adView ?? UIView()
    }
}

public class ADSuyiFlutterAdViewFactory : NSObject, FlutterPlatformViewFactory {
    public func create(withFrame frame: CGRect, viewIdentifier viewId: Int64, arguments args: Any?) -> FlutterPlatformView {
        let view = ADSuyiFlutterAdView()
        let adId = args as! Int
        view.adView = ADSuyiFlutterAdMap.shared.readAd(adId: adId) as? UIView
        return view
    }
    
    public func createArgsCodec() -> FlutterMessageCodec & NSObjectProtocol {
        return FlutterStandardMessageCodec.sharedInstance()
    }
}

class ADSuyiFlutterSplashAd : NSObject, ADSuyiSDKSplashAdDelegate {
    
    public static let shared = ADSuyiFlutterSplashAd()
    
    var adView : ADSuyiSDKSplashAd?
    // 加载开屏广告
    func loadAd(posid: String, adId: Int, imgName: String?, imgLogoName: String?) {
        let splash = requestSplashAd(posid: posid, adId: adId, imgName: imgName)
        if splash != nil {
           adView = splash
        }
        if let window = getWindow() {
            let bottomView = setupBottomViewWithLogoImageName(imgLogoName: imgLogoName)
            splash!.load(in: window, withBottomView: bottomView)//传入window(必传) 和 bottomView(非必传，如不需要可以传nil)参数
        }
    }
    // 展示开屏广告  需在loadAd后使用
    func showAd() {
        if let window = getWindow() {
            if adView != nil {
                adView!.show(in: window)//传入window(必传)
            }
        }
    }
    // 加载并展示开屏广告
    func loadAndShow(posid: String, adId: Int, imgName: String?, imgLogoName: String?) {
        let splash = requestSplashAd(posid: posid, adId: adId, imgName: imgName)
        if let window = getWindow() {
            let bottomView = setupBottomViewWithLogoImageName(imgLogoName: imgLogoName)
            splash!.loadAndShow(in: window, withBottomView: bottomView)//传入window(必传) 和 bottomView(非必传，如不需要可以传nil)参数
        }
    }
    // 初始化广告对象
    func requestSplashAd(posid: String, adId: Int, imgName: String?) -> ADSuyiSDKSplashAd?{
        var splash = ADSuyiFlutterAdMap.shared.readAd(adId: adId) as? ADSuyiSDKSplashAd
        if splash == nil {
            splash = ADSuyiSDKSplashAd()
            splash!.posId = posid // 设置广告位
            splash!.controller = getTopViewController() //设置最上层控制器
            splash!.delegate = self // 设置代理
            let image = UIImage(named: imgName ?? "")
            if(image != nil){
                splash!.backgroundColor = UIColor.adsy_get(with: image!, withNewSize: UIScreen.main.bounds.size) //设置过渡背景
            }
            ADSuyiFlutterAdMap.shared.saveAd(ad: splash!, adId: adId)
        }
        return splash
    }
    // 创建底部logo视图
    func setupBottomViewWithLogoImageName(imgLogoName: String?) -> UIView? {
        guard let logoName = imgLogoName else {
            return nil
        }
        
        guard let logoImage = UIImage(named: logoName) else {
            return nil
        }
        
        guard logoImage.size.height != 0 else {
            // Error: Logo image height is 0.
            return nil
        }
        
        let logoImageView = UIImageView(image: logoImage)
        let screenHeight: CGFloat = UIScreen.main.bounds.size.height
        let screenWidth: CGFloat = UIScreen.main.bounds.size.width
        var bottomViewHeight: CGFloat = screenHeight * 0.15
        let bottomViewHeightMax: CGFloat = screenHeight * 0.25
        if bottomViewHeight < 100 {
            bottomViewHeight = 100 <= bottomViewHeightMax ? 100 : bottomViewHeightMax
        }
        let bottomView = UIView(frame: CGRect(x: 0, y: screenHeight - bottomViewHeight, width: screenWidth, height: bottomViewHeight))
        
        bottomView.backgroundColor = UIColor.white

        // Set the logoImageView height to 60 and width to auto-scale
        let logoImageHeight: CGFloat = 54
        let logoImageWidth: CGFloat = (logoImage.size.width / logoImage.size.height) * logoImageHeight
        logoImageView.contentMode = .scaleAspectFit
        logoImageView.frame = CGRect(x: (screenWidth - logoImageWidth) / 2, y: (bottomViewHeight - logoImageHeight) / 2, width: logoImageWidth, height: logoImageHeight)
        bottomView.addSubview(logoImageView)
        
        return bottomView
    }
    

    
    // MARK: - ADSuyiSDKSplashAdDelegate
    
    func adsy_splashAdFail(toPresentScreen splashAd: ADSuyiSDKSplashAd, failToPresentScreen error: ADSuyiAdapterErrorDefine) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: splashAd)
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onFailed", arguments: ["adId" : adId, "error" : "错误", "errorCode" : error.code, "errorDescription" : error.errorDescription]);
    }
    
    func adsy_splashAdClosed(_ splashAd: ADSuyiSDKSplashAd) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: splashAd)
        let splashExtInfo:ADSuyiSDKExtInfo = splashAd.adsy_extInfo() ?? ADSuyiSDKExtInfo()
        let ecpmPrecision = getEcpmPrecisionWithType(type: Int(splashExtInfo.ecpmType.rawValue));
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onClosed", arguments: ["adId" : adId, "platformName" : splashAd.adsy_platform() ?? "", "ecpm":Double(splashExtInfo.ecpm) ?? 0, "ecpmPrecision":ecpmPrecision]);
    }
    
    func adsy_splashAdSuccess(toLoad splashAd: ADSuyiSDKSplashAd) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: splashAd)
        let splashExtInfo:ADSuyiSDKExtInfo = splashAd.adsy_extInfo() ?? ADSuyiSDKExtInfo()
        let ecpmPrecision = getEcpmPrecisionWithType(type: Int(splashExtInfo.ecpmType.rawValue));
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onSucced", arguments: ["adId" : adId, "platformName" : splashAd.adsy_platform() ?? "", "ecpm":Double(splashExtInfo.ecpm) ?? 0, "ecpmPrecision":ecpmPrecision]);
    }
    
    func adsy_splashAdSuccess(toPresentScreen splashAd: ADSuyiSDKSplashAd) {
        
    }

    func adsy_splashAdClicked(_ splashAd: ADSuyiSDKSplashAd) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: splashAd)
        let splashExtInfo:ADSuyiSDKExtInfo = splashAd.adsy_extInfo() ?? ADSuyiSDKExtInfo()
        let ecpmPrecision = getEcpmPrecisionWithType(type: Int(splashExtInfo.ecpmType.rawValue));
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onClicked", arguments: ["adId" : adId, "platformName" : splashAd.adsy_platform() ?? "", "ecpm":Double(splashExtInfo.ecpm) ?? 0, "ecpmPrecision":ecpmPrecision]);
    }

    func adsy_splashAdEffective(_ splashAd: ADSuyiSDKSplashAd) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: splashAd)
        let splashExtInfo:ADSuyiSDKExtInfo = splashAd.adsy_extInfo() ?? ADSuyiSDKExtInfo()
        let ecpmPrecision = getEcpmPrecisionWithType(type: Int(splashExtInfo.ecpmType.rawValue));
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onExposed", arguments: ["adId" : adId, "platformName" : splashAd.adsy_platform() ?? "", "ecpm":Double(splashExtInfo.ecpm) ?? 0, "ecpmPrecision":ecpmPrecision]);
    }
}

class ADSuyiFlutterRewardAd : NSObject, ADSuyiSDKRewardvodAdDelegate {
    func adsy_rewardvodAdServerDidSucceed(_ rewardvodAd: ADSuyiSDKRewardvodAd, info: [AnyHashable : Any]) {
        
    }
    
    func adsy_rewardvodAdCloseLandingPage(_ rewardvodAd: ADSuyiSDKRewardvodAd) {
        
    }
    
    
    public static let shared = ADSuyiFlutterRewardAd()
    
    func load(posId: String, adId: Int) {
        var reward = ADSuyiFlutterAdMap.shared.readAd(adId: adId) as? ADSuyiSDKRewardvodAd
        if reward == nil {
            reward = ADSuyiSDKRewardvodAd()
            reward?.posId = posId
            reward?.controller = getTopViewController()
            reward?.delegate = self
            ADSuyiFlutterAdMap.shared.saveAd(ad: reward!, adId: adId)
        }
        reward?.load()
    }
    
    func show(adId: Int) {
        if let reward = ADSuyiFlutterAdMap.shared.readAd(adId: adId) as? ADSuyiSDKRewardvodAd {
            reward.show()
        }
    }
    
    func adsy_rewardvodAdLoadSuccess(_ rewardvodAd: ADSuyiSDKRewardvodAd) { }
    
    func adsy_rewardvodAdReady(toPlay rewardvodAd: ADSuyiSDKRewardvodAd) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: rewardvodAd)
        let rewardvodExtInfo:ADSuyiSDKExtInfo = rewardvodAd.adsy_extInfo() ?? ADSuyiSDKExtInfo()
        let ecpmPrecision = getEcpmPrecisionWithType(type: Int(rewardvodExtInfo.ecpmType.rawValue));
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onSucced", arguments: ["adId" : adId, "platformName" : rewardvodAd.adsy_platform() ?? "", "ecpm":Double(rewardvodExtInfo.ecpm) ?? 0, "ecpmPrecision":ecpmPrecision]);
    }
    
    func adsy_rewardvodAdVideoLoadSuccess(_ rewardvodAd: ADSuyiSDKRewardvodAd) { }
    
    func adsy_rewardvodAdWillVisible(_ rewardvodAd: ADSuyiSDKRewardvodAd) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: rewardvodAd)
        let rewardvodExtInfo:ADSuyiSDKExtInfo = rewardvodAd.adsy_extInfo() ?? ADSuyiSDKExtInfo()
        let ecpmPrecision = getEcpmPrecisionWithType(type: Int(rewardvodExtInfo.ecpmType.rawValue));
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onExposed", arguments: ["adId" : adId, "platformName" : rewardvodAd.adsy_platform() ?? "", "ecpm":Double(rewardvodExtInfo.ecpm) ?? 0, "ecpmPrecision":ecpmPrecision]);
    }
    
    func adsy_rewardvodAdDidVisible(_ rewardvodAd: ADSuyiSDKRewardvodAd) { }
    
    func adsy_rewardvodAdDidClose(_ rewardvodAd: ADSuyiSDKRewardvodAd) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: rewardvodAd)
        let rewardvodExtInfo:ADSuyiSDKExtInfo = rewardvodAd.adsy_extInfo() ?? ADSuyiSDKExtInfo()
        let ecpmPrecision = getEcpmPrecisionWithType(type: Int(rewardvodExtInfo.ecpmType.rawValue));
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onClosed", arguments: ["adId" : adId, "platformName" : rewardvodAd.adsy_platform() ?? "", "ecpm":Double(rewardvodExtInfo.ecpm) ?? 0, "ecpmPrecision":ecpmPrecision]);
    }
    
    func adsy_rewardvodAdDidClick(_ rewardvodAd: ADSuyiSDKRewardvodAd) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: rewardvodAd)
        let rewardvodExtInfo:ADSuyiSDKExtInfo = rewardvodAd.adsy_extInfo() ?? ADSuyiSDKExtInfo()
        let ecpmPrecision = getEcpmPrecisionWithType(type: Int(rewardvodExtInfo.ecpmType.rawValue));
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onClicked", arguments: ["adId" : adId, "platformName" : rewardvodAd.adsy_platform() ?? "", "ecpm":Double(rewardvodExtInfo.ecpm) ?? 0, "ecpmPrecision":ecpmPrecision]);
    }
    
    func adsy_rewardvodAdDidPlayFinish(_ rewardvodAd: ADSuyiSDKRewardvodAd) { }
    
    func adsy_rewardvodAdDidRewardEffective(_ rewardvodAd: ADSuyiSDKRewardvodAd) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: rewardvodAd)
        let rewardvodExtInfo:ADSuyiSDKExtInfo = rewardvodAd.adsy_extInfo() ?? ADSuyiSDKExtInfo()
        let ecpmPrecision = getEcpmPrecisionWithType(type: Int(rewardvodExtInfo.ecpmType.rawValue));
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onRewarded", arguments: ["adId" : adId, "platformName" : rewardvodAd.adsy_platform() ?? "", "ecpm":Double(rewardvodExtInfo.ecpm) ?? 0, "ecpmPrecision":ecpmPrecision]);
    }
    
    func adsy_rewardvodAdFail(toLoad rewardvodAd: ADSuyiSDKRewardvodAd, errorModel: ADSuyiAdapterErrorDefine) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: rewardvodAd)
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onFailed", arguments: ["adId" : adId, "errorCode" : errorModel.code, "errorDescription" : errorModel.errorDescription]);
    }
    
    func adsy_rewardvodAdPlaying(_ rewardvodAd: ADSuyiSDKRewardvodAd, errorModel: ADSuyiAdapterErrorDefine) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: rewardvodAd)
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onFailed", arguments: ["adId" : adId]);
    }

    func adsy_rewardvodAdServerDidSucceed(_ rewardvodAd: ADSuyiSDKRewardvodAd) {   }
    
    func adsy_rewardvodAdServerDidFailed(_ rewardvodAd: ADSuyiSDKRewardvodAd, errorModel: ADSuyiAdapterErrorDefine) {   }


    
}

class ADSuyiFlutterIntertitialAd : NSObject, ADSuyiSDKIntertitialAdDelegate {
    func adsy_interstitialAdCloseLandingPage(_ interstitialAd: ADSuyiSDKIntertitialAd) {
        
    }
    
    
    public static let shared = ADSuyiFlutterIntertitialAd()
    
    func load(posId: String, adId: Int) {
        var inter = ADSuyiFlutterAdMap.shared.readAd(adId: adId) as? ADSuyiSDKIntertitialAd
        if inter == nil {
            inter = ADSuyiSDKIntertitialAd()
            inter?.posId = posId
            inter?.controller = getTopViewController()
            inter?.delegate = self
            ADSuyiFlutterAdMap.shared.saveAd(ad: inter!, adId: adId)
        }
        inter?.loadData()
    }
    
    func show(adId: Int) {
        if let inter = ADSuyiFlutterAdMap.shared.readAd(adId: adId) as? ADSuyiSDKIntertitialAd {
            inter.show()
        }
    }
    
    func adsy_interstitialAdSucced(toLoad interstitialAd: ADSuyiSDKIntertitialAd) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: interstitialAd)
        let interstitialExtInfo:ADSuyiSDKExtInfo = interstitialAd.adsy_extInfo() ?? ADSuyiSDKExtInfo()
        let ecpmPrecision = getEcpmPrecisionWithType(type: Int(interstitialExtInfo.ecpmType.rawValue));
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onSucced", arguments: ["adId" : adId, "platformName" : interstitialAd.adsy_platform() ?? "", "ecpm":Double(interstitialExtInfo.ecpm) ?? 0, "ecpmPrecision":ecpmPrecision]);
    }
    
    func adsy_interstitialAdFailed(toLoad interstitialAd: ADSuyiSDKIntertitialAd, error: ADSuyiAdapterErrorDefine) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: interstitialAd)
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onFailed", arguments: ["adId" : adId, "errorCode" : error.code, "errorDescription" : error.errorDescription]);
    }
    
    func adsy_interstitialAdDidPresent(_ interstitialAd: ADSuyiSDKIntertitialAd) { }
    
    func adsy_interstitialAdFailed(toPresent interstitialAd: ADSuyiSDKIntertitialAd, error: Error) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: interstitialAd)
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onFailed", arguments: ["adId" : adId]);
    }
    
    func adsy_interstitialAdDidClick(_ interstitialAd: ADSuyiSDKIntertitialAd) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: interstitialAd)
        let interstitialExtInfo:ADSuyiSDKExtInfo = interstitialAd.adsy_extInfo() ?? ADSuyiSDKExtInfo()
        let ecpmPrecision = getEcpmPrecisionWithType(type: Int(interstitialExtInfo.ecpmType.rawValue));
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onClicked", arguments: ["adId" : adId, "platformName" : interstitialAd.adsy_platform() ?? "", "ecpm":Double(interstitialExtInfo.ecpm) ?? 0, "ecpmPrecision":ecpmPrecision]);
    }
    
    func adsy_interstitialAdDidClose(_ interstitialAd: ADSuyiSDKIntertitialAd) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: interstitialAd)
        let interstitialExtInfo:ADSuyiSDKExtInfo = interstitialAd.adsy_extInfo() ?? ADSuyiSDKExtInfo()
        let ecpmPrecision = getEcpmPrecisionWithType(type: Int(interstitialExtInfo.ecpmType.rawValue));
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onClosed", arguments: ["adId" : adId, "platformName" : interstitialAd.adsy_platform() ?? "", "ecpm":Double(interstitialExtInfo.ecpm) ?? 0, "ecpmPrecision":ecpmPrecision]);
    }
    
    func adsy_interstitialAdExposure(_ interstitialAd: ADSuyiSDKIntertitialAd) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: interstitialAd)
        let interstitialExtInfo:ADSuyiSDKExtInfo = interstitialAd.adsy_extInfo() ?? ADSuyiSDKExtInfo()
        let ecpmPrecision = getEcpmPrecisionWithType(type: Int(interstitialExtInfo.ecpmType.rawValue));
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onExposed", arguments: ["adId" : adId, "platformName" : interstitialAd.adsy_platform() ?? "", "ecpm":Double(interstitialExtInfo.ecpm) ?? 0, "ecpmPrecision":ecpmPrecision]);
    }
}

class ADSuyiFlutterFullScreenVodAd : NSObject, ADSuyiSDKFullScreenVodAdDelegate {
    func adsy_fullScreenVodAdCloseLandingPage(_ fullScreenVodAd: ADSuyiSDKFullScreenVodAd) {
        
    }
    
    
    public static let shared = ADSuyiFlutterFullScreenVodAd()
    
    func load(posId: String, adId: Int) {
        var fullScreenVodAd = ADSuyiFlutterAdMap.shared.readAd(adId: adId) as? ADSuyiSDKFullScreenVodAd
        if fullScreenVodAd == nil {
            fullScreenVodAd = ADSuyiSDKFullScreenVodAd()
            fullScreenVodAd!.posId = posId
            fullScreenVodAd!.controller = getTopViewController()
            fullScreenVodAd!.delegate = self
            ADSuyiFlutterAdMap.shared.saveAd(ad: fullScreenVodAd!, adId: adId)
        }
        fullScreenVodAd!.loadData()
    }
    
    func show(adId: Int) {
        if let fullScreenVodAd = ADSuyiFlutterAdMap.shared.readAd(adId: adId) as? ADSuyiSDKFullScreenVodAd {
            fullScreenVodAd.show()
        }
    }
    
    func adsy_fullScreenVodAdSucced(toLoad fullScreenVodAd: ADSuyiSDKFullScreenVodAd) {
    }
    
    func adsy_fullScreenVodAdReady(toPlay fullScreenVodAd: ADSuyiSDKFullScreenVodAd) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: fullScreenVodAd)
        let fullScreenVodExtInfo:ADSuyiSDKExtInfo = fullScreenVodAd.adsy_extInfo() ?? ADSuyiSDKExtInfo()
        let ecpmPrecision = getEcpmPrecisionWithType(type: Int(fullScreenVodExtInfo.ecpmType.rawValue));
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onSucced", arguments: ["adId" : adId, "platformName" : fullScreenVodAd.adsy_platform() ?? "", "ecpm":Double(fullScreenVodExtInfo.ecpm) ?? 0, "ecpmPrecision":ecpmPrecision]);
    }
    
    func adsy_fullScreenVodAdSuccess(toLoadVideo fullScreenVodAd: ADSuyiSDKFullScreenVodAd) {
    }
    
    func adsy_fullScreenVodAdFailed(toLoad fullScreenVodAd: ADSuyiSDKFullScreenVodAd, error: ADSuyiAdapterErrorDefine) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: fullScreenVodAd)
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onFailed", arguments: ["adId" : adId, "errorCode" : error.code, "errorDescription" : error.errorDescription]);
    }
    
    func adsy_fullScreenVodAdDidPresent(_ fullScreenVodAd: ADSuyiSDKFullScreenVodAd) {
    }
    
    func adsy_fullScreenVodAdFail(toPresent fullScreenVodAd: ADSuyiSDKFullScreenVodAd, error: Error) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: fullScreenVodAd)
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onFailed", arguments: ["adId" : adId]);
    }
    
    func adsy_fullScreenVodAdDidClick(_ fullScreenVodAd: ADSuyiSDKFullScreenVodAd) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: fullScreenVodAd)
        let fullScreenVodExtInfo:ADSuyiSDKExtInfo = fullScreenVodAd.adsy_extInfo() ?? ADSuyiSDKExtInfo()
        let ecpmPrecision = getEcpmPrecisionWithType(type: Int(fullScreenVodExtInfo.ecpmType.rawValue));
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onClicked", arguments: ["adId" : adId, "platformName" : fullScreenVodAd.adsy_platform() ?? "", "ecpm":Double(fullScreenVodExtInfo.ecpm) ?? 0, "ecpmPrecision":ecpmPrecision]);
    }
    
    func adsy_fullScreenVodAdDidClose(_ fullScreenVodAd: ADSuyiSDKFullScreenVodAd) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: fullScreenVodAd)
        let fullScreenVodExtInfo:ADSuyiSDKExtInfo = fullScreenVodAd.adsy_extInfo() ?? ADSuyiSDKExtInfo()
        let ecpmPrecision = getEcpmPrecisionWithType(type: Int(fullScreenVodExtInfo.ecpmType.rawValue));
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onClosed", arguments: ["adId" : adId, "platformName" : fullScreenVodAd.adsy_platform() ?? "", "ecpm":Double(fullScreenVodExtInfo.ecpm) ?? 0, "ecpmPrecision":ecpmPrecision]);
    }
    
    func adsy_fullScreenVodAdExposure(_ fullScreenVodAd: ADSuyiSDKFullScreenVodAd) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: fullScreenVodAd)
        let fullScreenVodExtInfo:ADSuyiSDKExtInfo = fullScreenVodAd.adsy_extInfo() ?? ADSuyiSDKExtInfo()
        let ecpmPrecision = getEcpmPrecisionWithType(type: Int(fullScreenVodExtInfo.ecpmType.rawValue));
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onExposed", arguments: ["adId" : adId, "platformName" : fullScreenVodAd.adsy_platform() ?? "", "ecpm":Double(fullScreenVodExtInfo.ecpm) ?? 0, "ecpmPrecision":ecpmPrecision]);
    }
    
    func adsy_fullScreenVodAdPlayComplete(_ fullScreenVodAd: ADSuyiSDKFullScreenVodAd, didFailed error: Error?) {
    }
    
}

class ADSuyiFlutterBannerAd: NSObject, ADSuyiSDKBannerAdViewDelegate{
    func adsy_bannerViewDidPresent(_ bannerView: ADSuyiSDKBannerAdView) {
        
    }
    
    func adsy_bannerAdCloseLandingPage(_ bannerView: ADSuyiSDKBannerAdView) {
        
    }
    
    
    public static let shared = ADSuyiFlutterBannerAd()
    
    func load(posId: String, adId: Int, adWidth:Double, adHeight:Double) {
        var bannerAd = ADSuyiFlutterAdMap.shared.readAd(adId: adId) as? ADSuyiSDKBannerAdView
        if bannerAd == nil {
            bannerAd = ADSuyiSDKBannerAdView.init(frame: CGRect.init(x: 0, y: 0, width: adWidth, height: adHeight))
            bannerAd!.posId = posId
            bannerAd!.delegate = self
            ADSuyiFlutterAdMap.shared.saveAd(ad: bannerAd!, adId: adId)
        }
        bannerAd?.loadAndShow(getTopViewController()!)
    }
    
    func adsy_bannerViewDidReceived(_ bannerView: ADSuyiSDKBannerAdView) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: bannerView)
        let bannerExtInfo:ADSuyiSDKExtInfo = bannerView.adsy_extInfo() ?? ADSuyiSDKExtInfo()
        let ecpmPrecision = getEcpmPrecisionWithType(type: Int(bannerExtInfo.ecpmType.rawValue));
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onSucced", arguments: ["adId" : adId, "platformName" : bannerView.adsy_platform() ?? "", "ecpm":Double(bannerExtInfo.ecpm) ?? 0, "ecpmPrecision":ecpmPrecision]);
    }
    
    func adsy_bannerViewFail(toReceived bannerView: ADSuyiSDKBannerAdView, errorModel: ADSuyiAdapterErrorDefine) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: bannerView)
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onFailed", arguments: ["adId" : adId, "errorCode" : errorModel.code, "errorDescription" : errorModel.errorDescription]);
    }
    
    func adsy_bannerViewClicked(_ bannerView: ADSuyiSDKBannerAdView) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: bannerView)
        let bannerExtInfo:ADSuyiSDKExtInfo = bannerView.adsy_extInfo() ?? ADSuyiSDKExtInfo()
        let ecpmPrecision = getEcpmPrecisionWithType(type: Int(bannerExtInfo.ecpmType.rawValue));
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onClicked", arguments: ["adId" : adId, "platformName" : bannerView.adsy_platform() ?? "", "ecpm":Double(bannerExtInfo.ecpm) ?? 0, "ecpmPrecision":ecpmPrecision]);
    }
    
    func adsy_bannerViewClose(_ bannerView: ADSuyiSDKBannerAdView) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: bannerView)
        let bannerExtInfo:ADSuyiSDKExtInfo = bannerView.adsy_extInfo() ?? ADSuyiSDKExtInfo()
        let ecpmPrecision = getEcpmPrecisionWithType(type: Int(bannerExtInfo.ecpmType.rawValue));
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onClosed", arguments: ["adId" : adId, "platformName" : bannerView.adsy_platform() ?? "", "ecpm":Double(bannerExtInfo.ecpm) ?? 0, "ecpmPrecision":ecpmPrecision]);
    }
    
    func adsy_bannerViewExposure(_ bannerView: ADSuyiSDKBannerAdView) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: bannerView)
        let bannerExtInfo:ADSuyiSDKExtInfo = bannerView.adsy_extInfo() ?? ADSuyiSDKExtInfo()
        let ecpmPrecision = getEcpmPrecisionWithType(type: Int(bannerExtInfo.ecpmType.rawValue));
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onExposed", arguments: ["adId" : adId, "platformName" : bannerView.adsy_platform() ?? "", "ecpm":Double(bannerExtInfo.ecpm) ?? 0, "ecpmPrecision":ecpmPrecision]);
    }
    
}

class ADSuyiFlutterNativeAd : NSObject, ADSuyiSDKNativeAdDelegate {
    
    static let shared = ADSuyiFlutterNativeAd()

    var renderMap: NSMapTable<UIView, ADSuyiSDKNativeAd> = NSMapTable.strongToStrongObjects()

    func loadNativeAd(_ posId:String, adId:Int, width:CGFloat) {
        var loader = ADSuyiFlutterAdMap.shared.readAd(adId: adId) as? ADSuyiSDKNativeAd
        if(loader == nil) {
            loader = ADSuyiSDKNativeAd.init(adSize: CGSize(width: width, height: 0))
            loader!.delegate = self
            loader!.controller = getTopViewController()
            loader!.posId = posId
            ADSuyiFlutterAdMap.shared.saveAd(ad: loader!, adId: adId)
        }
        loader!.load(1)
    }

   // MARK: - ADSuyiSDKNativeAdDelegate

    func adsy_nativeAdSucess(toLoad nativeAd: ADSuyiSDKNativeAd, adViewArray: [UIView & ADSuyiAdapterNativeAdViewDelegate]) {
        for adView in adViewArray {
            if adView.renderType() == ADSuyiAdapterRenderType.native { // 自渲染信息流 可参照下面示例根据需求自行调整
                //1、常规样式
//                    setUpUnifiedNativeAdView(adview: item)
                //2、纯图
//                    setUpUnifiedOnlyImageNativeAdView(adview: item)
                //3、上图下文
                setUpUnifiedTopImageNativeAdView(adview: adView)
            }
            renderMap.setObject(nativeAd, forKey: adView)
            adView.adsy_registViews([adView])
        }
    }

    func adsy_nativeAdViewRenderOrRegistFail(_ adView: UIView & ADSuyiAdapterNativeAdViewDelegate) {
        guard let loader = renderMap.object(forKey: adView) else {
            return;
        }
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: loader)
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onFailed", arguments: ["adId" : adId]);
        renderMap.removeObject(forKey: adView)
    }
    
    func adsy_nativeAdFail(toLoad nativeAd: ADSuyiSDKNativeAd, errorModel: ADSuyiAdapterErrorDefine) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: nativeAd)
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onFailed", arguments: ["adId" : adId, "errorCode" : errorModel.code, "errorDescription" : errorModel.errorDescription]);
    }

    func adsy_nativeAdViewRenderOrRegistSuccess(_ adView: UIView & ADSuyiAdapterNativeAdViewDelegate) {
        guard let nativeAd = renderMap.object(forKey: adView) else {
            return;
        }
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: nativeAd)
        let adViewId = getNewAdId()
        ADSuyiFlutterAdMap.shared.saveAd(ad: adView, adId: adViewId)
        let nativeExtInfo:ADSuyiSDKExtInfo = adView.adsy_extInfo() ?? ADSuyiSDKExtInfo()
        let ecpmPrecision = getEcpmPrecisionWithType(type: Int(nativeExtInfo.ecpmType.rawValue));
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onReceived", arguments: ["adId" : adId, "adViewId" : adViewId, "adHeight": adView.frame.size.height, "adWidth": adView.frame.size.width, "platformName" : adView.adsy_platform() ?? "", "ecpm":Double(nativeExtInfo.ecpm) ?? 0, "ecpmPrecision":ecpmPrecision]);
        renderMap.removeObject(forKey: adView)
   }

    func adsy_nativeAdClose(_ nativeAd: ADSuyiSDKNativeAd, adView: UIView & ADSuyiAdapterNativeAdViewDelegate) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: adView)
        let nativeExtInfo:ADSuyiSDKExtInfo = adView.adsy_extInfo() ?? ADSuyiSDKExtInfo()
        let ecpmPrecision = getEcpmPrecisionWithType(type: Int(nativeExtInfo.ecpmType.rawValue));
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onClosed", arguments: ["adId" : adId, "platformName" : adView.adsy_platform() ?? "", "ecpm":Double(nativeExtInfo.ecpm) ?? 0, "ecpmPrecision":ecpmPrecision]);
    }

    func adsy_nativeAdClicked(_ nativeAd: ADSuyiSDKNativeAd, adView: UIView & ADSuyiAdapterNativeAdViewDelegate) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: adView)
        let nativeExtInfo:ADSuyiSDKExtInfo = adView.adsy_extInfo() ?? ADSuyiSDKExtInfo()
        let ecpmPrecision = getEcpmPrecisionWithType(type: Int(nativeExtInfo.ecpmType.rawValue));
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onClicked", arguments: ["adId" : adId, "platformName" : adView.adsy_platform() ?? "", "ecpm":Double(nativeExtInfo.ecpm) ?? 0, "ecpmPrecision":ecpmPrecision]);
    }

    func adsy_nativeAdExposure(_ nativeAd: ADSuyiSDKNativeAd, adView: UIView & ADSuyiAdapterNativeAdViewDelegate) {
        let adId = ADSuyiFlutterAdMap.shared.readAdId(ad: adView)
        let nativeExtInfo:ADSuyiSDKExtInfo = adView.adsy_extInfo() ?? ADSuyiSDKExtInfo()
        let ecpmPrecision = getEcpmPrecisionWithType(type: Int(nativeExtInfo.ecpmType.rawValue));
        SwiftAdSuyiFlutterSdkPlugin.channel!.invokeMethod("onExposed", arguments: ["adId" : adId, "platformName" : adView.adsy_platform() ?? "", "ecpm":Double(nativeExtInfo.ecpm) ?? 0, "ecpmPrecision":ecpmPrecision]);
    }
    // 1、常规样式
    func setUpUnifiedNativeAdView(adview : UIView & ADSuyiAdapterNativeAdViewDelegate) {
        // 设计的adView实际大小，其中宽度和高度可以自己根据自己的需求设置
        let adWidth:CGFloat = adview.frame.width
        let adHeight:CGFloat = (adWidth - 34.0) / 16.0 * 9.0 + 67 + 38
        adview.frame = CGRect.init(x: 0, y: 0, width: adWidth, height: adHeight)
        
        // 展示关闭按钮（必要）
        let closeButton = UIButton()
        adview.addSubview(closeButton)
        closeButton.frame = CGRect(x:adWidth-44, y:0, width:44, height:44)
        closeButton.setImage(UIImage(named: "close"), for: .normal)
        closeButton.addTarget(adview, action: #selector(adview.adsy_close), for: .touchUpInside)
        
        // 显示logo图片（必要）
        //优量汇（广点通）会自带logo，不需要添加
        if adview.adsy_platform() != ADSuyiAdapterPlatform.GDT {
            let logoImage = UIImageView()
            adview.addSubview(logoImage);
            adview.adsy_platformLogoImageDarkMode(false) { (image) in
                guard let image = image else {
                    return
                }
                let maxWidth: CGFloat = 80.0;
                let logoHeight = maxWidth / image.size.width * image.size.height;
                logoImage.frame = CGRect(x: adWidth - maxWidth, y: adHeight - logoHeight, width: maxWidth, height: logoHeight)
            }
        }

        // 设置标题文字（可选，但强烈建议带上）
        let titleLabel = UILabel.init()
        adview.addSubview(titleLabel)
        titleLabel.font = UIFont.adsy_PingFangMediumFont(14)
        titleLabel.textColor = UIColor.adsy_color(withHexString: "#333333")
        titleLabel.numberOfLines = 2
        titleLabel.text = adview.data?.title
        let size:CGSize = titleLabel.sizeThatFits(CGSize.init(width: adWidth - 34.0, height: 999))
        titleLabel.frame = CGRect.init(x: 17, y: 16, width: adWidth - 34.0, height: size.height)
        
        var height:CGFloat = size.height + 16 + 15
        
        // 设置主图/视频（主图可选，但强烈建议带上,如果有视频试图，则必须带上）
        let mainFrame:CGRect = CGRect.init(x: 17, y: height, width: adWidth - 34.0, height: (adWidth - 34.0) / 16.0 * 9.0)
        if adview.data?.shouldShowMediaView ?? false {
            let mediaView:UIView = adview.adsy_mediaView(forWidth: mainFrame.size.width) ?? UIView.init()
            mediaView.frame = mainFrame
            adview.addSubview(mediaView)
        } else {
            let imageView:UIImageView = UIImageView.init()
            imageView.backgroundColor = UIColor.adsy_color(withHexString: "#CCCCCC")
            adview.addSubview(imageView)
            imageView.frame = mainFrame
            
            let urlStr:String = adview.data?.imageUrl ?? ""
            if urlStr.count > 0 {
                DispatchQueue.global().async {
                    let url = URL.init(string: urlStr)
                    if url != nil {
                        let data = NSData.init(contentsOf: url!)
                        if data != nil {
                            let image = UIImage.init(data: data! as Data)
                            DispatchQueue.main.async {
                                imageView.image = image
                            }
                        }
                    }
                }
            }
        }
        
        height = height + (adWidth - 34.0) / 16.0 * 9.0 + 9.0
        
        // 设置广告标识（可选）
        let adlabel : UILabel = UILabel.init()
        adlabel.backgroundColor = UIColor.adsy_color(withHexString: "#CCCCCC")
        adlabel.textColor = UIColor.adsy_color(withHexString: "#FFFFFF")
        adlabel.font = UIFont.adsy_PingFangLightFont(12)
        adlabel.text = "广告"
        adview.addSubview(adlabel)
        adlabel.frame = CGRect.init(x: 17, y: height, width: 36, height: 18)
        adlabel.textAlignment = NSTextAlignment.center
        
        // 设置广告描述(可选)
        let descLabel : UILabel = UILabel.init()
        descLabel.textColor = UIColor.adsy_color(withHexString: "#333333")
        descLabel.font = UIFont.adsy_PingFangLightFont(12)
        descLabel.textAlignment = NSTextAlignment.left
        descLabel.text = adview.data?.desc
        adview.addSubview(descLabel)
        descLabel.frame = CGRect.init(x: 17 + 36 + 4, y: height, width: adWidth - 57 - 17 - 20, height: 18)
    }
    // 2、纯图
    func setUpUnifiedOnlyImageNativeAdView(adview : UIView & ADSuyiAdapterNativeAdViewDelegate) {
        // 设计的adView实际大小，其中宽度和高度可以自己根据自己的需求设置
        let adWidth:CGFloat = adview.frame.width
        let adHeight:CGFloat = adWidth / 16.0 * 9.0
        adview.frame = CGRect.init(x: 0, y: 0, width: adWidth, height: adHeight)
        
        
        // 设置主图/视频（主图可选，但强烈建议带上,如果有视频试图，则必须带上）
        let mainFrame:CGRect = CGRect.init(x: 0, y: 0, width: adWidth , height: adHeight)
        if adview.data?.shouldShowMediaView ?? false {
            let mediaView:UIView = adview.adsy_mediaView(forWidth: mainFrame.size.width) ?? UIView.init()
            mediaView.frame = mainFrame
            adview.addSubview(mediaView)
        } else {
            let imageView:UIImageView = UIImageView.init()
            imageView.backgroundColor = UIColor.adsy_color(withHexString: "#CCCCCC")
            adview.addSubview(imageView)
            imageView.frame = mainFrame
            
            let urlStr:String = adview.data?.imageUrl ?? ""
            if urlStr.count > 0 {
                DispatchQueue.global().async {
                    let url = URL.init(string: urlStr)
                    if url != nil {
                        let data = NSData.init(contentsOf: url!)
                        if data != nil {
                            let image = UIImage.init(data: data! as Data)
                            DispatchQueue.main.async {
                                imageView.image = image
                            }
                        }
                    }
                }
            }
        }
        
        // 展示关闭按钮（必要）
        let closeButton = UIButton()
        adview.addSubview(closeButton)
        closeButton.frame = CGRect(x:adWidth-44, y:0, width:44, height:44)
        closeButton.setImage(UIImage(named: "close"), for: .normal)
        closeButton.addTarget(adview, action: #selector(adview.adsy_close), for: .touchUpInside)
        
        // 显示logo图片（必要）
        if adview.adsy_platform() != ADSuyiAdapterPlatform.GDT {
            let logoImage = UIImageView()
            adview.addSubview(logoImage);
            adview.adsy_platformLogoImageDarkMode(false) { (image) in
                guard let image = image else {
                    return
                }
                let maxWidth: CGFloat = 80.0;
                let logoHeight = maxWidth / image.size.width * image.size.height;
                logoImage.frame = CGRect(x: adWidth - maxWidth, y: adHeight - logoHeight, width: maxWidth, height: logoHeight)
            }
        }

    }
    // 3、上图下文
    func setUpUnifiedTopImageNativeAdView(adview : UIView & ADSuyiAdapterNativeAdViewDelegate) {
        // 设计的adView实际大小，其中宽度和高度可以自己根据自己的需求设置
        let adWidth:CGFloat = adview.frame.width;
        let adHeight:CGFloat = (adWidth - 34.0) / 16.0 * 9.0 + 70
        adview.frame = CGRect.init(x: 0, y: 0, width: adWidth, height: adHeight)
        

        // 显示logo图片（必要）
        if adview.adsy_platform() != ADSuyiAdapterPlatform.GDT {
            let logoImage = UIImageView()
            adview.addSubview(logoImage);
            adview.adsy_platformLogoImageDarkMode(false) { (image) in
                guard let image = image else {
                    return
                }
                let maxWidth: CGFloat = 30.0;
                let logoHeight = maxWidth / image.size.width * image.size.height;
                logoImage.image = image
                logoImage.frame = CGRect(x: adWidth - maxWidth, y: adHeight - logoHeight, width: maxWidth, height: logoHeight)
            }
        }
        
        // 设置主图/视频（主图可选，但强烈建议带上,如果有视频试图，则必须带上）
        let mainFrame:CGRect = CGRect.init(x: 17, y: 0, width: adWidth - 34.0, height: (adWidth - 34.0) / 16.0 * 9.0)
        if adview.data?.shouldShowMediaView ?? false {
            let mediaView:UIView = adview.adsy_mediaView(forWidth: mainFrame.size.width) ?? UIView.init()
            mediaView.frame = mainFrame
            adview.addSubview(mediaView)
        } else {
            let imageView:UIImageView = UIImageView.init()
            imageView.backgroundColor = UIColor.adsy_color(withHexString: "#CCCCCC")
            adview.addSubview(imageView)
            imageView.frame = mainFrame
            
            let urlStr:String = adview.data?.imageUrl ?? ""
            if urlStr.count > 0 {
                DispatchQueue.global().async {
                    let url = URL.init(string: urlStr)
                    if url != nil {
                        let data = NSData.init(contentsOf: url!)
                        if data != nil {
                            let image = UIImage.init(data: data! as Data)
                            DispatchQueue.main.async {
                                imageView.image = image
                            }
                        }
                    }
                }
            }
        }
        
        // 设置广告标识（可选）
        let adlabel : UILabel = UILabel.init()
        adlabel.backgroundColor = UIColor.adsy_color(withHexString: "#CCCCCC")
        adlabel.textColor = UIColor.adsy_color(withHexString: "#FFFFFF")
        adlabel.font = UIFont.adsy_PingFangLightFont(12)
        adlabel.text = "广告"
        adview.addSubview(adlabel)
        adlabel.frame = CGRect.init(x: 17, y: (adWidth - 17 * 2) / 16.0 * 9 + 9, width: 36, height: 18)
        adlabel.textAlignment = NSTextAlignment.center
        
        // 设置广告描述(可选)
        let descLabel : UILabel = UILabel.init()
        descLabel.textColor = UIColor.adsy_color(withHexString: "#333333")
        descLabel.font = UIFont.adsy_PingFangLightFont(12)
        descLabel.textAlignment = NSTextAlignment.left
        descLabel.text = adview.data?.desc
        adview.addSubview(descLabel)
        descLabel.frame = CGRect.init(x: 17 + 36 + 4, y: (adWidth - 17 * 2) / 16.0 * 9 + 9, width: adHeight - 57 - 17 - 20, height: 18)
        
        // 设置标题文字（可选，但强烈建议带上）
        let titleLabel = UILabel.init()
        adview.addSubview(titleLabel)
        titleLabel.font = UIFont.adsy_PingFangMediumFont(14)
        titleLabel.textColor = UIColor.adsy_color(withHexString: "#333333")
        titleLabel.numberOfLines = 2
        titleLabel.text = adview.data?.title
        let size:CGSize = titleLabel.sizeThatFits(CGSize.init(width: adWidth - 34.0, height: 999))
        titleLabel.frame = CGRect.init(x: 17, y: adHeight-size.height, width: adWidth - 34.0, height: size.height)
        
        // 展示关闭按钮（必要）
        let closeButton = UIButton()
        adview.addSubview(closeButton)
        closeButton.frame = CGRect(x:adWidth-44, y:0, width:44, height:44)
        closeButton.setImage(UIImage(named: "close"), for: .normal)
        closeButton.addTarget(adview, action: #selector(adview.adsy_close), for: .touchUpInside)
        
    }

}

// MARK: Helper
 //获取当前window
func getWindow() -> UIWindow? {
    return UIApplication.shared.keyWindow;
}
 // 获取最上层控制器
func getTopViewController() -> UIViewController? {
    if let window = UIApplication.shared.keyWindow {
        return getTopViewController(from: window)
    }
    return nil
}

func getTopViewController(from window: UIWindow) -> UIViewController? {
    if let rootVc = window.rootViewController {
        return getTopViewController(from: rootVc)
    }
    return nil
}

func getTopViewController(from vc: UIViewController) -> UIViewController {
    if let newVc = vc.presentedViewController {
        return getTopViewController(from: newVc)
    }
    if let tvc = vc as? UITabBarController {
        if let newVc = tvc.selectedViewController {
            return getTopViewController(from: newVc)
        }
    }
    if let nvc = vc as? UINavigationController {
        if let newVc = nvc.topViewController {
            return getTopViewController(from: newVc)
        }
    }
    return vc
}
